const Setting = require('../models/setting.model');
const AppError = require('../utils/AppError');
const fs = require('fs').promises;
const path = require('path');
const multer = require('multer'); // 引入 multer
const { validationResult } = require('express-validator'); // 引入 validationResult

// --- Multer 配置 (用于 Logo 上传) ---
const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        const uploadPath = path.join(__dirname, '../../uploads/logos'); // 定义 logo 保存路径
        fs.mkdir(uploadPath, { recursive: true }).then(() => cb(null, uploadPath));
    },
    filename: function (req, file, cb) {
        const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
        cb(null, file.fieldname + '-' + uniqueSuffix + path.extname(file.originalname));
    }
});

const upload = multer({
    storage: storage,
    limits: { fileSize: 2 * 1024 * 1024 }, // 限制文件大小为 2MB
    fileFilter: function (req, file, cb) {
        const allowedTypes = /jpeg|jpg|png|gif|svg/;
        const mimetype = allowedTypes.test(file.mimetype);
        const extname = allowedTypes.test(path.extname(file.originalname).toLowerCase());
        if (mimetype && extname) {
            return cb(null, true);
        }
        cb(new AppError('只允许上传图片文件 (jpeg, jpg, png, gif, svg)', 400));
    }
}).single('logo'); // 对应表单字段名

// 获取系统设置 (返回所有字段，包括敏感信息，因为是管理员接口)
exports.getSettings = async (req, res, next) => {
  try {
    const settings = await Setting.findOne();
    // 返回所有字段，如果 settings 不存在则返回空对象
    res.json(settings || {}); 
  } catch (error) {
    next(new AppError('获取系统设置失败', 500));
  }
};

// 更新系统设置
exports.updateSettings = async (req, res, next) => {
  // 首先处理验证错误
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
  }

  try {
    let settings = await Setting.findOne();
    if (!settings) {
      settings = new Setting();
    }

    // 只更新请求体中存在的字段
    for (const key in req.body) {
        if (Object.hasOwnProperty.call(req.body, key)) {
            // 特殊处理密码字段，如果为空则不更新
            if ((key === 'password' || key === 'accessKeySecret' || key === 'secretKey') && !req.body[key]) {
                continue; 
            }
            settings[key] = req.body[key];
        }
    }

    await settings.save();
    res.json({ message: '设置已更新' });
  } catch (error) {
    console.error('更新设置失败:', error); // 打印详细错误
    next(new AppError('更新系统设置失败', 500));
  }
};

// 上传 Logo
exports.uploadLogo = (req, res, next) => {
    upload(req, res, async function (err) {
        if (err instanceof multer.MulterError) {
            // Multer 错误
            return next(new AppError(`上传Logo失败: ${err.message}`, 400));
        } else if (err) {
            return next(err);
        }

        // 文件上传成功
        if (!req.file) {
            return next(new AppError('没有选择文件', 400));
        }

        try {
            let settings = await Setting.findOne();
            if (!settings) {
                settings = new Setting();
            }

            // 删除旧 Logo (如果存在且不是默认 Logo)
            if (settings.logo && settings.logo.startsWith('/uploads/logos/')) {
                const oldLogoPath = path.join(__dirname, '../..', settings.logo);
                try {
                    await fs.unlink(oldLogoPath);
                } catch (unlinkError) {
                    console.warn('删除旧 Logo 文件失败:', unlinkError.message);
                }
            }

            // 更新 Logo 路径 (相对于服务器根目录的 URL)
            const logoUrl = `/uploads/logos/${req.file.filename}`;
            settings.logo = logoUrl;
            await settings.save();

            res.json({ message: 'Logo 上传成功', logoUrl });
        } catch (dbError) {
            // 如果数据库保存失败，尝试删除已上传的文件
            const uploadedFilePath = path.join(__dirname, '../../uploads/logos', req.file.filename);
            try {
                await fs.unlink(uploadedFilePath);
            } catch (cleanupError) {
                console.error('清理上传失败的 Logo 文件时出错:', cleanupError.message);
            }
            next(new AppError('更新 Logo 设置失败', 500));
        }
    });
};

// 清理系统缓存
exports.clearCache = async (req, res, next) => {
  try {
    const cacheDir = path.join(__dirname, '../../uploads/cache');
    await fs.rm(cacheDir, { recursive: true, force: true });
    await fs.mkdir(cacheDir, { recursive: true });
    res.json({ message: '缓存已清理' });
  } catch (error) {
    next(new AppError('清理缓存失败', 500));
  }
};

// 备份数据
exports.backup = async (req, res, next) => {
  try {
    const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
    const backupDir = path.join(__dirname, '../../backups');
    const backupPath = path.join(backupDir, `backup-${timestamp}`);

    // 确保备份目录存在
    await fs.mkdir(backupDir, { recursive: true });

    // 获取所有集合的数据
    const collections = [
      { model: require('../models/user.model'), name: 'users' },
      { model: require('../models/video.model'), name: 'videos' },
      { model: require('../models/category.model'), name: 'categories' },
      { model: require('../models/comment.model'), name: 'comments' },
      { model: require('../models/setting.model'), name: 'settings' }
    ];

    // 备份每个集合的数据
    for (const collection of collections) {
      const data = await collection.model.find();
      await fs.writeFile(
        path.join(backupPath, `${collection.name}.json`),
        JSON.stringify(data, null, 2)
      );
    }

    res.json({
      message: '备份已完成',
      backupPath: `backup-${timestamp}`
    });
  } catch (error) {
    next(new AppError('创建备份失败', 500));
  }
};

// 获取备份列表
exports.getBackups = async (req, res, next) => {
  try {
    const backupDir = path.join(__dirname, '../../backups');
    const files = await fs.readdir(backupDir);
    
    const backups = await Promise.all(
      files.map(async (file) => {
        const stat = await fs.stat(path.join(backupDir, file));
        return {
          name: file,
          size: stat.size,
          createdAt: stat.birthtime
        };
      })
    );

    res.json(backups.sort((a, b) => b.createdAt - a.createdAt));
  } catch (error) {
    next(new AppError('获取备份列表失败', 500));
  }
};

// 恢复备份
exports.restoreBackup = async (req, res, next) => {
  try {
    const { backupId } = req.params;
    const backupDir = path.join(__dirname, '../../backups', backupId);

    // 检查备份是否存在
    try {
      await fs.access(backupDir);
    } catch {
      return next(new AppError('备份不存在', 404));
    }

    // 恢复每个集合的数据
    const collections = [
      { model: require('../models/user.model'), name: 'users' },
      { model: require('../models/video.model'), name: 'videos' },
      { model: require('../models/category.model'), name: 'categories' },
      { model: require('../models/comment.model'), name: 'comments' },
      { model: require('../models/setting.model'), name: 'settings' }
    ];

    for (const collection of collections) {
      const dataFile = path.join(backupDir, `${collection.name}.json`);
      const data = JSON.parse(await fs.readFile(dataFile, 'utf8'));
      
      // 清空现有数据
      await collection.model.deleteMany({});
      
      // 导入备份数据
      if (data.length > 0) {
        await collection.model.insertMany(data);
      }
    }

    res.json({ message: '备份已恢复' });
  } catch (error) {
    next(new AppError('恢复备份失败', 500));
  }
};

// 删除备份
exports.deleteBackup = async (req, res, next) => {
  try {
    const { backupId } = req.params;
    const backupPath = path.join(__dirname, '../../backups', backupId);

    await fs.rm(backupPath, { recursive: true, force: true });
    res.json({ message: '备份已删除' });
  } catch (error) {
    next(new AppError('删除备份失败', 500));
  }
};

// 测试邮件配置
exports.testEmail = async (req, res, next) => {
  try {
    const { host, port, user, pass, from } = req.body;
    
    // 创建邮件传输对象
    const transporter = require('nodemailer').createTransport({
      host,
      port,
      secure: port === 465,
      auth: { user, pass }
    });

    // 发送测试邮件
    await transporter.sendMail({
      from,
      to: user,
      subject: '邮件配置测试',
      text: '如果您收到这封邮件，说明邮件配置正确。'
    });

    res.json({ message: '测试邮件已发送' });
  } catch (error) {
    next(new AppError('发送测试邮件失败', 500));
  }
};

// 测试存储配置
exports.testStorage = async (req, res, next) => {
  try {
    const { type, config } = req.body;
    const testFile = path.join(__dirname, '../../uploads/test.txt');
    const testContent = 'Storage configuration test.';

    // 创建测试文件
    await fs.writeFile(testFile, testContent);

    let success = false;
    if (type === 'local') {
      // 测试本地存储
      const stat = await fs.stat(testFile);
      success = stat.size > 0;
    } else if (type === 's3') {
      // 测试 S3 存储
      const AWS = require('aws-sdk');
      const s3 = new AWS.S3(config);
      
      await s3.putObject({
        Bucket: config.bucket,
        Key: 'test.txt',
        Body: testContent
      }).promise();

      success = true;
    }

    // 清理测试文件
    await fs.unlink(testFile);

    if (success) {
      res.json({ message: '存储配置测试成功' });
    } else {
      throw new Error('存储测试失败');
    }
  } catch (error) {
    next(new AppError('存储配置测试失败', 500));
  }
};